#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

using std::vector;
using std::cin;
using std::cout;
using std::set;
using std::pair;
using std::make_pair;
using std::min;

class Graph {
    struct Vertex {
        int interval_number;
        bool type; // 0 - begin, 1 - end
        vector <Vertex*> edges;
        Vertex(): interval_number(0), type(0) {}
        Vertex(int interval_number_in, bool type_in, Graph *graph) :
                interval_number(interval_number_in), type(type_in){
        }

        void add_edge(Vertex &a) {
            edges.push_back(&a);
        }
    };

    int count;
    vector <Vertex> vertices;

    void add_vertex(int interval_number, bool type) {
        vertices.push_back(Vertex(interval_number, type, this));
    }

    void dfs(int current_number, vector <int> &used, vector <Vertex*> &path, bool &is_cycled) {
        if (is_cycled) {
            return;
        }
        used[current_number] = 1;
        for (auto it = vertices[current_number].edges.begin();
             it != vertices[current_number].edges.end(); ++it) {
            int vertex_number = get_vertex_number((*it)->interval_number, (*it)->type);
            if (used[vertex_number] == 0) {
                dfs(vertex_number, used, path, is_cycled);
            } else if (used[vertex_number] == 1) {
                is_cycled = true;
            }
        }
        used[current_number] = 2;
        path.push_back(&vertices[current_number]);
    }

 public:
    Graph(): count(0) {}
    Graph(int n): count(n * 2) {
        vertices.reserve(n * 2);
        for (int i = 0; i < n; ++i) {
            vertices.push_back(Vertex(i + 1, 0, this));
            vertices.push_back(Vertex(i + 1, 1, this));
            add_edge(i * 2, i * 2 + 1);
        }
    }
    void reserve(int n) {
        vertices.reserve(n * 2);
    }
    static int get_vertex_number(int interval_number, bool type) {
        return (interval_number - 1) * 2 + type;
    }
    void add_edge (int from, int to) {
        vertices[from].add_edge(vertices[to]);
    }
    void add_following(int left, int right) {
        add_edge(get_vertex_number(left, 0), get_vertex_number(right, 0));
        add_edge(get_vertex_number(left, 0), get_vertex_number(right, 1));
        add_edge(get_vertex_number(left, 1), get_vertex_number(right, 0));
        add_edge(get_vertex_number(left, 1), get_vertex_number(right, 1));
    }
    void add_intersection(int left, int right) {
        add_edge(get_vertex_number(left, 0), get_vertex_number(right, 1));
        add_edge(get_vertex_number(right, 0), get_vertex_number(left, 1));
    }
    vector < pair<int, int> > find_interval_location(bool &is_impossible) {
        vector < pair<int, int> > location(count / 2, make_pair(0, 0));
        vector <int> used(count, false);
        vector <Vertex*> path;
        path.reserve(count);
        bool is_cycled;
        for (int  i = 0; i < count; ++i) {
            if (used[i] == 0) {
                dfs(i, used, path, is_cycled);
            }
        }
        reverse(path.begin(), path.end());
        if (is_cycled) {
            is_impossible = false;
        } else {
            int number = 0;
            for (auto &current : path) {
                if (current->type == 0) {
                    location[current->interval_number - 1].first = number;
                } else {
                    location[current->interval_number - 1].second = number;
                }
                ++number;
            }
        }
        return location;
    };
};

int main () {
    int n, a, b;
    cin >> n >> a >> b;
    Graph graph(n);
    for (int i = 0; i < a; ++i) {
        int left, right;
        cin >> left >> right;
        graph.add_following(left, right);
    }
    for (int i = 0; i < b; ++i) {
        int left, right;
        cin >> left >> right;
        graph.add_intersection(left, right);
    }
    bool is_impossible = true;
    vector < pair<int, int> > location = graph.find_interval_location(is_impossible);

    if (is_impossible) {
        for (auto it : location) {
            cout << it.first << " " << it.second << std::endl;
        }
    } else {
        cout << "Impossible";
    }
}
